package com.wtwd.campus.attendancenetty;

import com.wtwd.campus.common.Constants;
import com.wtwd.campus.utils.DecoderUtils;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * @Author ldaoliang
 * @Date create in 13:05 2021/12/6
 * @Description
 */
public class MessageDecoder2 extends ByteToMessageDecoder {

    private static final Logger LOGGER = LoggerFactory.getLogger(MessageDecoder2.class);

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 可读长度不能小于基本长度
        if(in.readableBytes() < 4){
            return;
        }
        // 寻找起始值
        int beginReadIndex;
        String messageData = "";
        while (true){
            // 获取当前的读索引位置，并且标记
            beginReadIndex = in.readerIndex();
            in.markReaderIndex();
            // 可读长度不能小于基本长度
            if(in.readableBytes() < 4){
                return;
            }
            String begin = readData(in,1);
            // 有可能读到了
            if("5A".equalsIgnoreCase(begin)){
                String data = readProtocolData(in);
                if(data == null){
                    LOGGER.info("本次数据长度不够，等待下一包进来继续读取");
                    // 重置到 5A 之前的，等待下次数据足够时，直接从5A开始
                    in.resetReaderIndex();
                    return;
                }else if("".equals(data)){
                    LOGGER.info("本次读取数据不符合格式，丢弃当前包开头数据，继续读取");
                    // 回退到5A之前的index，把5A读掉，并且进行下一个循环。直到读到5A的正常报
                    in.resetReaderIndex();
                    in.readByte();
                }else{
                    messageData = "5A" + data;
                    break;
                }
            }
        }
        if(!"".equals(messageData)){
            out.add(messageData.toUpperCase());
        }
    }

    public String readData(ByteBuf buffer, int length) {
        byte[] data = new byte[length];
        buffer.readBytes(data);
        String hexStringData = DecoderUtils.byte2HexStr(data);
        return hexStringData;
    }



    /**
     * 读取协议数据
     * @param buffer
     * @return
     */
    public String readProtocolData(ByteBuf buffer){
        String cmd = readData(buffer,1);
        if(Constants.HEART_BEAT.equalsIgnoreCase(cmd) || Constants.TIME_CHECK.equalsIgnoreCase(cmd) || Constants.IDENTITY.equalsIgnoreCase(cmd) || Constants.SEND_DATA.equalsIgnoreCase(cmd)){
            String len = readData(buffer,2);
            // 16进制转正常数据
            int length = Integer.parseInt(len,16);
            // 剩余可读字节小于length + 2(2是xor 和 end符号)
            if(buffer.readableBytes() < length + 2){
                return null;
            }
            // 剩余长度足够。读取所有数据，进行XOR校验以及后面自己是否为CA结尾
            StringBuilder stringBuilder = new StringBuilder(cmd + len);
            String body = readData(buffer, length);
            stringBuilder.append(body);
            String xor = readData(buffer,1);
            String end = readData(buffer,1);
            // 校验xor和end
            String xorCode = DecoderUtils.checkCode(stringBuilder.toString());
            if(!xor.equalsIgnoreCase(xorCode)){
                return "";
            }
            if(!"CA".equalsIgnoreCase(end)){
                return "";
            }
            return stringBuilder.append(xor).append(end).toString();
        }else{
            // 则表示该5A并不是开头数据
            return "";
        }
    }





}
